<?php

declare(strict_types=1);

namespace App\CustHub\Service;

use App\CustHub\Amqp\Producers\SendRecordProducers;
use App\CustHub\Constants\RoomWelcomeConstants;
use App\CustHub\Constants\SendConfigConstants;
use App\CustHub\Dto\SendRecordProducersDto;
use Hyperf\Amqp\Producer;
use Hyperf\Redis\Redis;
use Mine\Abstracts\AbstractService;

class ChRoomWelcomeSendService extends AbstractService
{
    // Redis 键前缀
    private const ROOM_DATA_KEY = 'room_welcome_data';

    private Redis $redis;

    private ChSendConfigService $sendConfigService;

    public function __construct(Redis $redis,ChSendConfigService $sendConfigService)
    {
        $this->redis = $redis;
        $this->sendConfigService = $sendConfigService;
    }

    /**
     * 更新进群数据，并触发相关的逻辑（人数、时间触发等）
     * @param mixed $robotId 机器人ID
     * @param mixed $roomWxid 群微信ID
     * @param string $sceneMode 场景模式（member, time, both）
     * @param array $messageData 消息数据
     * @param int $memberThreshold 人数触发阈值
     * @param int $timeTriggerThreshold 时间触发阈值
     * @param int $memberCount 群成员数量
     * @return bool
     * @throws \RedisException
     */
    public function updateRoomData(mixed $robotId,mixed $roomWxid, string $sceneMode, array $messageData, int $memberThreshold, int $timeTriggerThreshold,int $memberCount): bool
    {
        // 更新进群人数
        $this->redis->hIncrBy(self::ROOM_DATA_KEY, "join_count:{$roomWxid}", $memberCount);

        // 1. 判断是否达到了入群人数阈值（根据场景）
        $isSend = false;

        if ($sceneMode == RoomWelcomeConstants::SCENE_MODE_MEMBER || $sceneMode == RoomWelcomeConstants::SCENE_MODE_BOTH) {
            $isSend = $this->checkMemberThreshold($robotId,$roomWxid, $messageData, $memberThreshold);
        }

        if (!$isSend && ($sceneMode == RoomWelcomeConstants::SCENE_MODE_TIME || $sceneMode == RoomWelcomeConstants::SCENE_MODE_BOTH)) {
            $isSend = $this->checkJoinTimeTrigger($robotId,$roomWxid, $messageData, $timeTriggerThreshold);
        }
        // 设置 TTL：活跃群组 TTL（24小时），不活跃群组 TTL（7天）
        $this->setroomTTL($roomWxid);
        return $isSend;
    }

    /**
     * 检查进群人数是否达到阈值，若达标则发送欢迎语
     * @param mixed $robotId
     * @param mixed $roomWxid
     * @param int $memberThreshold
     * @return bool
     * @throws \RedisException
     */
    private function checkMemberThreshold(mixed $robotId,mixed $roomWxid, array $messageData, int $memberThreshold): bool
    {
        $joinCount = (int)$this->redis->hGet(self::ROOM_DATA_KEY, "join_count:{$roomWxid}");

        // 如果进群人数达到了阈值，发送欢迎语
        if ($joinCount >= $memberThreshold) {
            $this->sendWelcomeMessage($robotId,$roomWxid, $messageData, '人数触发');
            $this->resetJoinCount($roomWxid);
            $this->redis->hSet(self::ROOM_DATA_KEY, "last_welcome_time:{$roomWxid}", microtime(true)); // 更新时间
            return true;
        }
        return false;
    }

    /**
     * 根据进群时间触发消息发送（6秒内不重复发送）
     * @param mixed $robotId
     * @param mixed $roomWxid
     * @param int $timeTriggerThreshold
     * @return bool
     * @throws \RedisException
     */
    private function checkJoinTimeTrigger(mixed $robotId,mixed $roomWxid, array $messageData, int $timeTriggerThreshold): bool
    {
        $currentTime = microtime(true);
        $lastJoinTime = (float)$this->redis->hGet(self::ROOM_DATA_KEY, "last_welcome_time:{$roomWxid}");
        // 判断最后一次进群的时间与当前时间的差值
        if ($lastJoinTime == null || ($currentTime - $lastJoinTime) > $timeTriggerThreshold) {
            $this->sendWelcomeMessage($robotId,$roomWxid, $messageData, '时间触发');
            $this->redis->hSet(self::ROOM_DATA_KEY, "last_welcome_time:{$roomWxid}", $currentTime); // 更新时间
            return true;
        }
        return false;
    }

    /**
     * 发送欢迎语
     *
     * @param mixed $robotId 机器人ID
     * @param mixed $roomWxid 群微信Id
     * @param array $messageData 消息数据
     * @param string $triggerType 触发类型（人数触发或时间触发）
     * @return void
     */
    public function sendWelcomeMessage(mixed $robotId,mixed $roomWxid, array $messageData, string $triggerType): void
    {
        $lock = 'send_welcome_message_lock:'.$roomWxid.'_'.$robotId;

        if($this->redis->get($lock)){
            return;
        }
        $this->redis->set($lock,1,2);

        // 这里可以放置实际的消息发送逻辑
        $content = $messageData['content'];
        $sendConfig = $this->sendConfigService->getConfig(SendConfigConstants::ROOM_WELCOME,$messageData['main_uid'],$robotId);
        //发送消息
        foreach ($content as $k=> $item){
            if($k > 0){
                $messageSendInterval = mt_rand($sendConfig['send_msg_interval_min'], $sendConfig['send_msg_interval_max']);
                $content[$k]['extra'] = [
                    'limit' => [
                        'unit' =>1,
                        'value' => $messageSendInterval
                    ]
                ];
            }
        }
        $recordData[] = [
            'uid' => $messageData['uid'],
            'main_uid' => $messageData['main_uid'],
            'task_id' => $messageData['id'],
            'robot_id' => $robotId,
            'to_id' => $roomWxid,
            'trigger_time' => time(),
            'content' => $content,
            'msg_total_count' => 1,
            'type' => SendConfigConstants::ROOM_WELCOME,
            'is_room' => 1
        ];

        container()->get(Producer::class)->produce(new SendRecordProducers(
            (new SendRecordProducersDto())
                ->setMainUid($messageData['main_uid'])
                ->setUid($messageData['uid'])
                ->setTaskId($messageData['id'])
                ->setType(SendConfigConstants::ROOM_WELCOME)
                ->setRecordData($recordData)
                ->setIsSendNow(true)
        ));
    }

    /**
     * 重置进群人数为0
     * @param mixed $roomWxid
     * @return void
     * @throws \RedisException
     */
    private function resetJoinCount(mixed $roomWxid): void
    {
        // 重置进群人数
        $this->redis->hSet(self::ROOM_DATA_KEY, "join_count:{$roomWxid}", 0);
        echo "进群人数已重置\n";
    }

    /**
     * 设置群组数据的 TTL
     *
     * @param int $roomWxid 群组ID
     * @return void
     */
    private function setRoomTTL(mixed $roomWxid): void
    {
        $lastActiveTime = (float)$this->redis->hGet(self::ROOM_DATA_KEY, "last_welcome_time:{$roomWxid}");

        // 如果群组长时间没有活跃，设置为较短的 TTL（7天）
        if ($lastActiveTime && (microtime(true) - $lastActiveTime) > 604800) {
            // 设置为不活跃的群组 TTL（7天）
            $this->redis->expire(self::ROOM_DATA_KEY, RoomWelcomeConstants::INACTIVE_ROOM_TTL);
        } else {
            // 如果群组最近活跃，设置为较长的 TTL（24小时）
            $this->redis->expire(self::ROOM_DATA_KEY, RoomWelcomeConstants::ACTIVE_ROOM_TTL);
        }
    }
}